package com.xb.loan.encryptor.crypt;


import com.xb.loan.encryptor.classloader.CryptographClassLoader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class EncryptorManager {
	
	private static Log log = LogFactory.getLog(EncryptorManager.class);
	
	private static Map<String, Encryptor> encryptorMap;
	
	static{
		
		init();
	}
	
	public static Encryptor getEncryptor(String type){
		
		return encryptorMap.get(type);
	}

	private static void init() {
		
		Properties props = readAsProperties("config/encryptor.properties");
		// 类加载器
		CryptographClassLoader loader = new CryptographClassLoader(Thread.currentThread().getContextClassLoader());
		
		encryptorMap = new HashMap<String, Encryptor>();
		
		Set<Object> keys = props.keySet();
		
		for (Object key : keys) {
			
			Encryptor encryptor = newInstance(props.getProperty((String) key), loader);
			
			if(encryptor != null){
				
				encryptorMap.put((String) key, encryptor);
				
				log.info("EncryptorManager.init put " + key + " type encryptor to map,class:" + props.getProperty((String) key));
			}
		}
		
	}
	
	private static Encryptor newInstance(String encryptorClass, ClassLoader loader){
		
		try {
			
			Class<?> clazz = Class.forName(encryptorClass, true, loader);
			
			Object obj = clazz.getConstructor().newInstance();
			
			return (Encryptor) obj;
			
		} catch (Exception e) {
			
			log.error("EncryptorManager.newInstance class have an exception,class:" + encryptorClass,e);
			
			return null;
		}
	}
	
	private static Properties readAsProperties(String name) {

		InputStream in = null;
		Properties prop = null;
		try {
			in = Thread.currentThread().getContextClassLoader().getResourceAsStream(name);

			prop = new Properties();

			prop.load(in);

		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		} finally {

			if (in != null) {

				try {

					in.close();
				} catch (IOException e) {

					e.printStackTrace();
				}
			}

		}

		return prop;
	}
	
	public static void main(String[] args) {
		
		System.out.println(getEncryptor("user"));
	}
	
}
